package com.example.demo.service.impl;

import com.example.demo.base.DepData;
import com.example.demo.service.StanfordNlpService;
import edu.stanford.nlp.ling.CoreLabel;
import edu.stanford.nlp.ling.IndexedWord;
import edu.stanford.nlp.pipeline.CoreDocument;
import edu.stanford.nlp.pipeline.CoreSentence;
import edu.stanford.nlp.pipeline.StanfordCoreNLP;
import edu.stanford.nlp.semgraph.SemanticGraph;
import edu.stanford.nlp.semgraph.SemanticGraphEdge;
import org.apache.catalina.Pipeline;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
public class StanfordNlpServiceImpl implements StanfordNlpService {


    private StanfordCoreNLP stanfordCoreNLP = new StanfordCoreNLP("StanfordCoreNLP-chinese.properties");


    @Override
    public List<String> getSentences(String text) {

        if(text==null)
            throw new NullPointerException("Text is Null");

        CoreDocument coreDocument =new CoreDocument(text);
        stanfordCoreNLP.annotate(coreDocument);

        List<String> sentences=new ArrayList<String>();

        for(CoreSentence sentence : coreDocument.sentences())
            sentences.add(sentence.text());
        return sentences;
    }

    @Override
    public List<String> getPos(String text) {
        if(text==null)
            throw new NullPointerException("Text is Null");

        CoreDocument coreDocument =new CoreDocument(text);
        stanfordCoreNLP.annotate(coreDocument);

        List<String> pos=new ArrayList<String>();

        for(CoreLabel word : coreDocument.tokens())
            pos.add(word.tag());
        return pos;
    }

    @Override
    public List<String> getWords(String text) {
        if(text==null)
            throw new NullPointerException("Text is Null");

        CoreDocument coreDocument =new CoreDocument(text);
        stanfordCoreNLP.annotate(coreDocument);

        List<String> words=new ArrayList<String>();

        for(CoreLabel word : coreDocument.tokens())
            words.add(word.word());
        return words;
    }


    @Override
    public DepData getDep(String text) {
        if(text==null)
            throw new NullPointerException("Text is Null");

        CoreDocument coreDocument =new CoreDocument(text);
        stanfordCoreNLP.annotate(coreDocument);

        List<SemanticGraph> dep=new ArrayList<SemanticGraph>();

        for( CoreSentence sentence : coreDocument.sentences()){
            SemanticGraph dependencyParse = sentence.dependencyParse();
            dep.add(dependencyParse);
        }

        List <List<Integer>> index=new ArrayList<List<Integer>>();
        List<String> roots= new ArrayList<String>();
        List<IndexedWord> iw=new ArrayList<IndexedWord>();
        for( SemanticGraph s : dep){

            for (IndexedWord root : s.topologicalSort()){
                //des.add(root.word());
                for (  SemanticGraphEdge sge :s.getOutEdgesSorted(root)){
                    IndexedWord source=sge.getSource();
                    IndexedWord tagert=sge.getTarget();
                    String relation=sge.getRelation().toString();
                    Integer sIndex=-1;
                    Integer tIndex=-1;
                    Integer rIndex=-1;
                    if(!iw.contains(source)){
                        roots.add(source.word());
                        sIndex=roots.size()-1;
                        iw.add(source);
                    }
                    else
                        sIndex=roots.indexOf(source.word());
                    if (!iw.contains(tagert)) {
                        roots.add(tagert.word());
                        tIndex=roots.size()-1;
                        iw.add(tagert);
                    }
                    else
                        tIndex=roots.indexOf(tagert.word());
                    roots.add(relation);
                    rIndex=roots.size()-1;
                    if(rIndex>=0 && sIndex>=0 && tIndex>=0){
                        List<Integer> sr= Arrays.asList(sIndex,rIndex);
                        List<Integer> rt= Arrays.asList(rIndex,tIndex);
                        index.add(sr);
                        index.add(rt);
                    }

                }
            }

        }
        DepData depData = new DepData();
        depData.setIndex(index);
        depData.setRoots(roots);
        return depData;
    }
}
